#include "NetworkManager.h"
#include "TcpSocket.h"

NetworkManager* NetworkManager::m_Singleton = 0;

NetworkManager::NetworkManager()
{
	assert(!m_Singleton);
	m_Singleton = this;
	cocos2d::Director::getInstance()->getScheduler()->scheduleUpdate<NetworkManager>(this, 0, false);
#ifdef WIN32
	WSADATA wsaData;
	WORD version = MAKEWORD(2, 0);
	int ret = WSAStartup(version, &wsaData);//win sock start up
#endif
}

NetworkManager::~NetworkManager()
{
#ifdef WIN32
	WSACleanup();
#endif
	cocos2d::Director::getInstance()->getScheduler()->unscheduleUpdate(this);
}

NetworkManager* NetworkManager::getSingleton()
{
	assert(m_Singleton);
	return m_Singleton;
}

void NetworkManager::update(float dt)
{
	if (m_lstSockets.empty()) return;
	for (SocketList::iterator iter = m_lstSockets.begin(); iter != m_lstSockets.end(); ++iter)
	{
		if (*iter)
		{
			(*iter)->polling();
		}
	}
}

TCPSocket* NetworkManager::createSocket(const char* pszServerIP, int nServerPort, int _tag, NetworkProtocol* protocol,
																	int nBlockSec /* = BLOCKSECONDS */, bool bKeepAlive /* = false */)
{
	TCPSocket* socket = new TCPSocket();
	if (socket->create(pszServerIP, nServerPort, _tag, protocol, nBlockSec, bKeepAlive))
	{
		if (addSocket(socket))
		{
			return socket;
		}
	}
	delete socket;
	return 0;
}

bool NetworkManager::addSocket(TCPSocket *pSocket)
{
	if (!pSocket) return false;
	for (SocketList::iterator iter = m_lstSockets.begin(); iter != m_lstSockets.end(); ++iter)
	{
		if ((*iter)->getSocket() == pSocket->getSocket()) return false;
	}
	m_lstSockets.push_back(pSocket);
	return true;
}

bool NetworkManager::removeSocket(int _tag)
{
	if (m_lstSockets.empty()) return false;
	for (SocketList::iterator iter = m_lstSockets.begin(); iter != m_lstSockets.end(); ++iter)
	{
		if ((*iter)->getTagID() == _tag)
		{
			TCPSocket* socket = (*iter);
			socket->destroy();
			m_lstSockets.erase(iter);
			delete socket;
			return true;
		}
	}
	return false;
}

TCPSocket* NetworkManager::findSocket(int _tag)
{
	if (m_lstSockets.empty()) return 0;
	for (SocketList::iterator iter = m_lstSockets.begin(); iter != m_lstSockets.end(); ++iter)
	{
		if ((*iter)->getTagID() == _tag)
		{
			TCPSocket* socket = (*iter);
			return socket;
		}
	}
	return 0;
}

void NetworkManager::callRemoteCommand(TCPSocket* socket, int cmd_id, ...)
{
	if (!socket) return;

	va_list args;
	va_start(args,cmd_id);
	socket->callRemoteCommand(cmd_id, &args);
	va_end(args);
}

void NetworkManager::callRemoteCommand(int socket_tag, int cmd_id, ...)
{
	TCPSocket* socket = findSocket(socket_tag);
	if (!socket) return;

	va_list args;
	va_start(args, cmd_id);
	socket->callRemoteCommand(cmd_id, &args);
	va_end(args);
}
